<script setup lang="ts">
import { useComponent } from "@visual/stores";
import { onMounted, ref, toRaw, watch } from "vue";
import { storeToRefs } from "pinia";
import { PxMessage } from "px-ui";
import AceEditor from "@visual/components/Editor/AceEditor.vue";
import { classNamePathMap, deepcopy, filterNestedByKeys, getValueByPath } from "@visual/utils";

const componentStore = useComponent();
const { changeDataBinding, changeDataAliase } = componentStore;
const { curComponent } = storeToRefs(componentStore);

const showDataBindingDialog = ref(false);
const props = defineProps({
  visualData: {
    type: Array,
    default: () => []
  }
});
const selected = ref();
const optionsData = ref([]);
const dataPath = ref("");
const datafilter = ref("");

const bindingData = ref({});
const aceBindRef = ref();
let dataKeys = Object.keys(curComponent.value.propValue);
let dataBinding = curComponent.value.dataBinding;
const aceRef = ref();
const dataList = ref(
  dataKeys.map(item => {
    return {
      raw: item,
      alias: ""
    };
  })
);
function reset() {
  selected.value = null;
  dataPath.value = "";
  bindingData.value = {};
  datafilter.value = "";
}
function setData() {
  let config = toRaw(curComponent.value);
  dataKeys = Object.keys(config.propValue);
  dataBinding = config.dataBinding;

  if (optionsData.value.length === 0) {
    const optionsDataRaw = deepcopy(props.visualData || []);
    optionsData.value = optionsDataRaw.map(item => {
      return {
        label: item.name,
        value: item,
        id: item.uniqueName
      };
    });
  }

  if (dataBinding && JSON.stringify(dataBinding) !== "{}") {
    let { path, type, val, filter } = dataBinding;
    dataPath.value = path;
    datafilter.value = filter;
    //这里数据回显时最好置灰
    selected.value = optionsData.value.find(item => {
      return item.id === type;
    });
    bindingData.value = val;
  }

  dataList.value = [];

  if (curComponent.value.dataAliase && JSON.stringify(curComponent.value.dataAliase) !== "{}") {
    for (let key in curComponent.value.dataAliase) {
      dataList.value.push({
        raw: key,
        alias: curComponent.value.dataAliase[key]
      });
    }
  } else {
    dataList.value = dataKeys.map(item => {
      return {
        raw: item,
        alias: ""
      };
    });
  }
}
watch([() => curComponent.value.id, showDataBindingDialog], ([new1, new2], [old1, old2]) => {
  if (new1 || new2) {
    setData();
  }
});
onMounted(() => {
  setData();
});
function submitComponentEvents() {
  let aceValue = aceRef.value.getValue();
  let res = aceValue.reduce((acc, cur) => {
    acc[cur.raw] = cur.alias;
    return acc;
  }, {});
  changeDataAliase(res);

  PxMessage({
    message: "数据保存成功",
    type: "success"
  });
}

function handleClose() {
  showDataBindingDialog.value = false;
  reset();
}
function optChange() {
  bindingData.value = deepcopy(selected.value);
}
function findPath() {
  let filterData = deepcopy(selected.value);
  if (dataPath.value !== "") {
    filterData = getValueByPath(filterData, dataPath.value);
  }

  if (datafilter.value !== "") {
    filterData = filterNestedByKeys(filterData, datafilter.value);
  }
  bindingData.value = filterData;
}

function bindingSave() {
  const { id } = selected.value;

  const data = { type: id, path: dataPath.value, filter: datafilter.value, val: aceBindRef.value.getValue() };
  if (data.val?.value) {
    const { className } = data.val?.value;
    if (className) {
      curComponent.value["classConfig"].className = className;
      curComponent.value["classConfig"].routerPath = classNamePathMap[className];
      curComponent.value["conditionFilter"] = `dep_${className}`;
    }
  }
  changeDataBinding(data);
  PxMessage({
    message: "数据保存成功",
    type: "success"
  });
  showDataBindingDialog.value = false;
}
</script>
<template>
  <div v-if="curComponent" class="attr-list mt-[14px]">
    <AceEditor ref="aceRef" :config-json="dataList" class="mb-[10px]" />
    <px-button style="margin-bottom: 10px" @click="submitComponentEvents">保存设置</px-button>
    <div class="mt-[14px]">
      <px-button style="margin-bottom: 10px" @click="showDataBindingDialog = true">设置绑定数据</px-button>
    </div>
  </div>

  <px-dialog v-model="showDataBindingDialog" destroy-on-close title="设置绑定数据" width="50%" @closed="handleClose">
    <div class="m-4">
      <div style="margin: 20px" />
      <px-form label-position="right" label-width="100px" style="max-width: 460px">
        <px-form-item label="选择数据源">
          <px-select v-model="selected" value-key="id" placeholder="Select" style="width: 240px" @change="optChange">
            <px-option v-for="item in optionsData" :key="item.id" :label="item.label" :value="item" />
          </px-select>
        </px-form-item>
        <px-form-item label="数据访问路径">
          <px-input v-model="dataPath" class="mb-[10px]" placeholder="请输入数据路径" />
          <px-input v-model="datafilter" placeholder="请输入数据筛选" />
          <px-button class="mt-[10px]" @click="findPath">搜索</px-button>
        </px-form-item>
      </px-form>
      <h3>数据源</h3>
      <AceEditor ref="aceBindRef" :config-json="bindingData" class="mb-[10px]" />
    </div>
    <template #footer>
      <span class="dialog-footer">
        <px-button @click="handleClose">取消</px-button>
        <px-button type="primary" @click="bindingSave"> 确定 </px-button>
      </span>
    </template>
  </px-dialog>
</template>

<!-- <style lang="scss" scoped></style> -->
